package cn.zymall.common.utils.redis;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * @author xuxianda
 * @Description: redis分布式锁
 * @date 2020/8/19 20:38
 * @Copyright
 * @return
 **/
@Component
public class RedisLock {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 获取一个redis分布锁
     * 推荐requestId使用UUID
     *
     * @param lockKey   锁住的key
     * @param requestId 请求ID
     * @return
     */
    public boolean lock(String lockKey, String requestId) {
        boolean locked = false;
        int tryCount = 3;
        /**
         * 自旋锁
         */
        while (!locked && tryCount > 0) {
            /**
             * 先锁他个一分钟测试一下锁好不好用 哈哈
             */

            /**
             * redis：setIfAbsent的作用是：
             *      如果键不存在则新增,存在则不改变已经有的值。
             */
            locked = redisTemplate.opsForValue().setIfAbsent(lockKey, requestId, 2, TimeUnit.MINUTES);
            tryCount--;
            try {
                /**
                 *  线程睡眠300毫秒
                 */
                Thread.sleep(300);
            } catch (InterruptedException e) {
                e.printStackTrace();
                /**
                 * 报错了就要返回一个false 不能把500页面给用户看
                 */
                return false;
            }
        }
        return locked;
    }

    /**
     * 释放锁
     * 必须requestId一致才能释放锁
     *
     * @param lockKey
     * @param requestId
     * @return
     */
    public boolean unlock(String lockKey, String requestId) {
        if (redisTemplate.opsForValue().get(lockKey).equals(requestId)) {
            System.out.println(true);
        }
        return redisTemplate.delete(lockKey);
    }
}
